import { NestFactory } from '@nestjs/core';
import { UserModule } from './user.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { grpcServerOptions } from '@app/grpc/utils/grpc-server/grpc-server.options';
import { NacosRegisterService } from '@app/nacos-register';
import { EtcdRegisterService } from '@app/etcd-register';

async function bootstrap() {
  /**
   * gRPC 微服务远程调用 5000
   * 跨语言通信 端口
   */
  const gRPCApp = await NestFactory.createMicroservice(
    UserModule,
    grpcServerOptions,
  ); // 启动 gRPC 微服务
  await gRPCApp.listen();
  console.log('gRPC 启动...');
  /**
   * TCP 微服务
   */
  const TCPApp = await NestFactory.createMicroservice<MicroserviceOptions>(
    UserModule,
    {
      transport: Transport.TCP,
      options: {
        host: 'localhost',
        port: 5002,
      },
    },
  );
  // 注册中心 nacos
  const nacosService = TCPApp.get(NacosRegisterService);
  await nacosService.registerService('user-service');
  // 注册中心 etcd
  const etcdService = TCPApp.get(EtcdRegisterService);
  await etcdService.registerService('user-service');

  TCPApp.enableShutdownHooks();
  // 挂载TCP
  await TCPApp.listen();
  /**
   * 关闭服务并注销
   */
  process.on('SIGINT', async () => {
    // 注销服务nacos
    await nacosService.romoveService('user-service');
    // 注销服务etcd
    await etcdService.romoveService('user-service');

    process.exit(0);
  });
  /**
   * HTTP 微服务
   */
  const app = await NestFactory.create(UserModule);
  app.enableCors({
    origin: '*',
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    allowedHeaders: 'Content-Type, Authorization',
  });

  app.setGlobalPrefix('user');
  const config = new DocumentBuilder()
    .setTitle('用户服务')
    .setDescription('用户服务 API 文档')
    .setVersion('1.0')
    .addBearerAuth({
      type: 'http',
      description: '基于 jwt 的认证',
    })
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('swagger-docs', app, document);
  await app.listen(5102);
}
bootstrap();
